package common;

public class base64encoder {
	private static final String base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
			+ "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/";

	private static final int splitLinesAt = 76;

	public static byte[] zeroPad(int length, byte[] bytes) {
		byte[] padded = new byte[length];
		System.arraycopy(bytes, 0, padded, 0, bytes.length);
		return padded;
	}

	private static String encode(byte[] ByteArray )
	{
		String encoded = "";
		// On determine le nombre de paddind qu'il faut ajouter
		int paddingCount = (3 - (ByteArray.length % 3)) % 3;
		// On bourre des zero pour le padding
		ByteArray = zeroPad(ByteArray.length + paddingCount, ByteArray);
		// On traite par 24 bits.
		for (int i = 0; i < ByteArray.length; i += 3) { 
			// On decale les 8 premiers bits vers 8 bits de poids fort
			int j =   ((ByteArray[i    ] & 0xff) << 16) 
			// On decale les 8 seconds bits vers les 8 bits de poids moyen
					+ ((ByteArray[i + 1] & 0xff) << 8)  
					+ ( ByteArray[i + 2] & 0xff);
			// On determine pour chaque 6 bits le caractere correspondant
			// et on range dans la string
			encoded = encoded								
					+ base64code.charAt((j >> 18) & 0x3f)   
					+ base64code.charAt((j >> 12) & 0x3f)
					+ base64code.charAt((j >> 6)  & 0x3f)
					+ base64code.charAt( j        & 0x3f);
		}
		// on ajoute les padding et on coupe en ligne de 76 caracteres.
		return splitLines(encoded.substring(0, encoded.length() - paddingCount)	+ "==".substring(0, paddingCount));
	}
	
	public static String decode(String StringtoDecode )
	{
		String sResult ="";
		StringtoDecode = StringtoDecode.replaceAll("(\\r|\\n)",""); // On rassemble les lignes
		int nbPad = 0;
		if ( StringtoDecode.indexOf("=") != -1 )
		{
			// On calcul le nombre de caractere de padding
			nbPad = StringtoDecode.length() - StringtoDecode.substring(0, StringtoDecode.indexOf("=")).length(); 
		}
		int TailleString = (StringtoDecode.length());
		int idx = 0;
		for ( idx = 0; idx < TailleString  ; idx += 4)
		{
				int result = ( 
					(base64code.indexOf(StringtoDecode.charAt(idx))   & 0x3f) << 18)
				+ ( (base64code.indexOf(StringtoDecode.charAt(idx+1)) & 0x3f) << 12);
				if ( idx+2 < TailleString - nbPad )
					result = result + ( (base64code.indexOf(StringtoDecode.charAt(idx+2)) & 0x3f) << 6 );
				if ( idx+3 < TailleString - nbPad )		
					result = result+ ( (base64code.indexOf(StringtoDecode.charAt(idx+3)) & 0x3f  ));
							
			sResult = sResult + (char)((result >> 16)& 0xff) +  (char)( (result >> 8 ) & 0xff ) +  (char)( (result) & 0xff );
		}
	return 	sResult;
	}
	public static String encode(String string) {
		byte[] stringArray;
		try {
			stringArray = string.getBytes("UTF-8"); 													
		} catch (Exception ignored) {
			stringArray = string.getBytes(); 
		}
		return encode(stringArray);
	}

	
	public static String splitLines(String string) {
		String lines = "";
		for (int i = 0; i < string.length(); i += splitLinesAt) {
			lines += string.substring(i, Math.min(string.length(), i+ splitLinesAt));
			lines += "\r\n";
		}
		return lines;
	}
}

